/**
 * Copyright &copy; 2012-2016 <a href="https://github.com/thinkgem/ccjzxyxt">ccjzxyxt</a> All rights reserved.
 */
package cn.net.dckj.modules.sys.web;

import cn.net.dckj.common.config.Global;
import cn.net.dckj.common.security.shiro.session.SessionDAO;
import cn.net.dckj.common.servlet.ValidateCodeServlet;
import cn.net.dckj.common.utils.CacheUtils;
import cn.net.dckj.common.utils.CookieUtils;
import cn.net.dckj.common.utils.IdGen;
import cn.net.dckj.common.utils.StringUtils;
import cn.net.dckj.common.web.BaseController;
import cn.net.dckj.modules.sys.security.FormAuthenticationFilter;
import cn.net.dckj.modules.sys.security.SystemAuthorizingRealm;
import cn.net.dckj.modules.sys.utils.UserUtils;
import com.google.common.collect.Maps;
import org.apache.shiro.authz.UnauthorizedException;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.web.util.WebUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;

/**
 * 登录Controller
 *
 * @author ThinkGem
 * @version 2013-5-31
 */
@Controller
public class LoginController extends BaseController {

    @Autowired
    private SessionDAO sessionDAO;

    // 网站登录地址
    private String getFrontLoginUrl() {
        return "redirect:" + frontPath;
    }
    // 管理登录地址
    //private String adminLoginUrl = "redirect:/admin/login";

    // 管理端登录页面
    private String adminLoginPage = "modules/sys/sysLogin";
    // 管理端登录首页
    private String adminIndexPage = "modules/sys/sysIndex";

    /**
     * 系统登录(主登录页面)
     */
    @RequestMapping(value = "${adminPath}/login", method = RequestMethod.GET)
    public String login(HttpServletResponse response) {
        return loginRedirect(response, getFrontLoginUrl());
    }

    /**
     * 其他登录（后台登录页面）
     */
    @RequestMapping(value = "/admin/login", method = RequestMethod.GET)
    public String loginAdmin(HttpServletResponse response) {
        return loginRedirect(response, adminLoginPage);
    }

    /**
     * 登录失败，真正登录的POST请求由Filter完成
     */
    @RequestMapping(value = "${adminPath}/login", method = RequestMethod.POST)
    public String loginFail(HttpServletRequest request, HttpServletResponse response, Model model) {
        SystemAuthorizingRealm.Principal principal = UserUtils.getPrincipal();

        // 如果已经登录，则跳转到管理首页
        String format = WebUtils.getCleanParam(request, "format");
        String origin = WebUtils.getCleanParam(request, "origin");
        if (principal != null) {
            /*return "redirect:" + adminPath;*/
            if ("page".equals(format)) {
                if (("back").equals(origin)) {
                    return adminIndexPage;
                } else {
                    return getFrontLoginUrl();
                }
            } else {
                model.addAttribute("success", true);
                model.addAttribute("message", "用户已经登录！");
                return renderString(response, model);
            }
        }

        String username = WebUtils.getCleanParam(request, FormAuthenticationFilter.DEFAULT_USERNAME_PARAM);
        boolean rememberMe = WebUtils.isTrue(request, FormAuthenticationFilter.DEFAULT_REMEMBER_ME_PARAM);
        boolean mobile = WebUtils.isTrue(request, FormAuthenticationFilter.DEFAULT_MOBILE_PARAM);
        String exception = (String) request.getAttribute(FormAuthenticationFilter.DEFAULT_ERROR_KEY_ATTRIBUTE_NAME);
        String message = (String) request.getAttribute(FormAuthenticationFilter.DEFAULT_MESSAGE_PARAM);

        if (StringUtils.isBlank(message) || StringUtils.equals(message, "null")) {
            message = "用户或密码错误, 请重试.";
        }

        model.addAttribute(FormAuthenticationFilter.DEFAULT_USERNAME_PARAM, username);
        model.addAttribute(FormAuthenticationFilter.DEFAULT_REMEMBER_ME_PARAM, rememberMe);
        model.addAttribute(FormAuthenticationFilter.DEFAULT_MOBILE_PARAM, mobile);
        model.addAttribute(FormAuthenticationFilter.DEFAULT_ERROR_KEY_ATTRIBUTE_NAME, exception);
        model.addAttribute(FormAuthenticationFilter.DEFAULT_MESSAGE_PARAM, message);

        if (logger.isDebugEnabled()) {
            logger.debug("login fail, active session size: {}, message: {}, exception: {}",
                    sessionDAO.getActiveSessions(false).size(), message, exception);
        }

        // 非授权异常，登录失败，验证码加1。
        if (!UnauthorizedException.class.getName().equals(exception)) {
            model.addAttribute("isValidateCodeLogin", isValidateCodeLogin(username, true, false, format));
        }

        // 验证失败清空验证码
        request.getSession().setAttribute(ValidateCodeServlet.VALIDATE_CODE, IdGen.uuid());

        // 如果是手机登录，则返回JSON字符串
        if (mobile) {
            return renderString(response, model);
        }

        if ("page".equals(format)) {
            if (("back").equals(origin)) {
                return adminLoginPage;
            } else {
                return getFrontLoginUrl();
            }
        } else {
            model.addAttribute("success", false);
            return renderString(response, model);
        }
    }

    /**
     * 登录成功，进入管理首页
     */
    @RequiresPermissions("user")
    @RequestMapping(value = "${adminPath}")
    public String index(HttpServletRequest request, HttpServletResponse response, Model model) {
        SystemAuthorizingRealm.Principal principal = UserUtils.getPrincipal();

        String format = principal.getFormat();
        String origin = principal.getOrigin();

        // 登录成功后，验证码计算器清零
        isValidateCodeLogin(principal.getLoginName(), false, true, format);

        if (logger.isDebugEnabled()) {
            logger.debug("show index, active session size: {}", sessionDAO.getActiveSessions(false).size());
        }

        // 如果已登录，再次访问主页，则退出原账号。
        if (Global.TRUE.equals(Global.getConfig("notAllowRefreshIndex"))) {
            String logined = CookieUtils.getCookie(request, "LOGINED");
            if (StringUtils.isBlank(logined) || "false".equals(logined)) {
                CookieUtils.setCookie(response, "LOGINED", "true");
            } else if (StringUtils.equals(logined, "true")) {
                UserUtils.getSubject().logout();
                if ("page".equals(format)) {
                    if (("back").equals(origin)) {
                        return adminLoginPage;
                    } else {
                        return getFrontLoginUrl();
                    }
                } else {
                    model.addAttribute("success", false);
                    model.addAttribute("message", "请重新登录！");
                    return renderString(response, model);
                }
            }
        }

        // 如果是手机登录，则返回JSON字符串
        if (principal.isMobileLogin()) {
            if (request.getParameter("login") != null) {
                return renderString(response, principal);
            }
            if (request.getParameter("index") != null) {
                return adminIndexPage;
            }
            return "redirect:" + adminPath + "/login";
        }

//		// 登录成功后，获取上次登录的当前站点ID
//		UserUtils.putCache("siteId", StringUtils.toLong(CookieUtils.getCookie(request, "siteId")));

//		System.out.println("==========================a");
//		try {
//			byte[] bytes = FileUtils.readFileToByteArray(
//					FileUtils.getFile("c:\\sxt.dmp"));
//			UserUtils.getSession().setAttribute("kkk", bytes);
//			UserUtils.getSession().setAttribute("kkk2", bytes);
//		} catch (Exception e) {
//			e.printStackTrace();
//		}
////		for (int i=0; i<1000000; i++){
////			//UserUtils.getSession().setAttribute("a", "a");
////			request.getSession().setAttribute("aaa", "aa");
////		}
//		System.out.println("==========================b");


        if ("page".equals(format)) {
            if (("back").equals(origin)) {
                return "modules/sys/sysIndex";
                /*// 通过登录用户类型可控制改变跳转页面
                User user = UserUtils.getUser();
                String userType = user.getUserType();
                if (userType.equals("1")) {
                    return "modules/sys/sysIndex";
                } else {
                    return getFrontLoginPage();
                }*/
            } else {
                return getFrontLoginUrl();
            }
        } else {
            model.addAttribute("success", "true");
            model.addAttribute("message", "系统登录成功！");
            model.addAttribute("id", principal.getId());
            return renderString(response, model);
        }
    }

    /**
     * 获取主题方案
     */
    @RequestMapping(value = "/theme/{theme}")
    public String getThemeInCookie(@PathVariable String theme, HttpServletRequest request, HttpServletResponse response) {
        if (StringUtils.isNotBlank(theme)) {
            CookieUtils.setCookie(response, "theme", theme);
        } else {
            theme = CookieUtils.getCookie(request, "theme");
        }
        return "redirect:" + request.getParameter("url");
    }

    /**
     * 是否是验证码登录
     *
     * @param useruame 用户名
     * @param isFail   计数加1
     * @param clean    计数清零
     * @return
     */
    @SuppressWarnings("unchecked")
    public static boolean isValidateCodeLogin(String useruame, boolean isFail, boolean clean, String format) {
        if (!"page".equals(format)) {
            String frontValidateCodeLogin = Global.getConfig("frontValidateCodeLogin");
            if ("false".equals(frontValidateCodeLogin)) {
                return false;
            }
        }
        Map<String, Integer> loginFailMap = (Map<String, Integer>) CacheUtils.get("loginFailMap");
        if (loginFailMap == null) {
            loginFailMap = Maps.newHashMap();
            CacheUtils.put("loginFailMap", loginFailMap);
        }
        Integer loginFailNum = loginFailMap.get(useruame);
        if (loginFailNum == null) {
            loginFailNum = 0;
        }
        if (isFail) {
            loginFailNum++;
            loginFailMap.put(useruame, loginFailNum);
        }
        if (clean) {
            loginFailMap.remove(useruame);
        }
        return loginFailNum >= 3;
    }

    protected String loginRedirect(HttpServletResponse response, String redirectPath) {
        SystemAuthorizingRealm.Principal principal = UserUtils.getPrincipal();
//		// 默认页签模式
//		String tabmode = CookieUtils.getCookie(request, "tabmode");
//		if (tabmode == null){
//			CookieUtils.setCookie(response, "tabmode", "1");
//		}

        if (logger.isDebugEnabled()) {
            logger.debug("login, active session size: {}", sessionDAO.getActiveSessions(false).size());
        }

        // 如果已登录，再次访问主页，则退出原账号。
        if (Global.TRUE.equals(Global.getConfig("notAllowRefreshIndex"))) {
            CookieUtils.setCookie(response, "LOGINED", "false");
        }

        // 如果已经登录，则跳转到管理首页
        if (principal != null && !principal.isMobileLogin()) {
            return redirectPath;
        }
//		String view;
//		view = "/WEB-INF/views/modules/sys/sysLogin.jsp";
//		view = "classpath:";
//		view += "jar:file:/D:/GitHub/ccjzxyxt/src/main/webapp/WEB-INF/lib/ccjzxyxt.jar!";
//		view += "/"+getClass().getName().replaceAll("\\.", "/").replace(getClass().getSimpleName(), "")+"view/sysLogin";
//		view += ".jsp";
        String result = "";
        if (StringUtils.isEmpty(redirectPath)) {
            result = adminLoginPage;
        } else {
            result = redirectPath;
        }
        return result;
    }
}
